import ReactECharts from 'echarts-for-react';
import 'echarts-gl';
import React, { useRef } from 'react';
import { fitChartSize } from '../utils/tools';
import Styles from './StationType.less';

// 数据格式
export type StationTypeData = {
  stationTypeName: string;
  num: number;
  stationProportion: number;
};

// 组件参数类型
type Pie3DProps = {
  data?: StationTypeData[];
  statusData?: StationTypeData[];
  distance?: number;
  alpha?: number;
  autoRotate?: boolean;
  thickness?: number; // 厚度参数
  widthRatio?: number; // 宽度参数
  internalDiameterRatio?: number; // 新增内径比例参数
};

const colors = ['#5C12E1', '#DCDA4F', '#10DD8F', '#0550DD', '#ED7B0F', '#F94847'];

const StationType: React.FC<Pie3DProps> = ({
  data,
  statusData,
  distance = 180,
  alpha = 30,
  autoRotate = true,
  thickness = 1.5, // 默认厚度值
  widthRatio = 1, // 默认宽度值
  internalDiameterRatio = 0.8, // 默认内径比例
}) => {
  const chartRef1 = useRef(null);
  const chartRef2 = useRef(null);
  const pieWrapRef = useRef(null);
  const getParametricEquation = (
    startRatio: number,
    endRatio: number,
    isSelected: boolean,
    isHovered: boolean,
    k: number,
    h: number,
    thickness: number, // 厚度参数
    widthRatio: number, // 宽度参数
  ) => {
    const midRatio = (startRatio + endRatio) / 2;
    const startRadian = startRatio * Math.PI * 2;
    const endRadian = endRatio * Math.PI * 2;
    const midRadian = midRatio * Math.PI * 2;
    // eslint-disable-next-line no-param-reassign
    k = typeof k !== 'undefined' ? k : 1 / 3;
    const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
    const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
    const hoverRate = isHovered ? 1.05 : 1;
    return {
      u: {
        min: -Math.PI,
        max: Math.PI * 3,
        step: Math.PI / 32,
      },
      v: {
        min: 0,
        max: Math.PI * 2,
        step: Math.PI / 20,
      },
      x: function (u: number, v: number) {
        if (u < startRadian) {
          return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate * widthRatio;
        }
        if (u > endRadian) {
          return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate * widthRatio;
        }
        return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate * widthRatio;
      },
      y: function (u: number, v: number) {
        if (u < startRadian) {
          return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
        }
        if (u > endRadian) {
          return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
        }
        return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
      },
      z: function (u: number, v: number) {
        if (u < -Math.PI * 0.5) {
          return Math.sin(u) * thickness; // 使用厚度参数
        }
        if (u > Math.PI * 2.5) {
          return Math.sin(u) * h * 0.1 * thickness; // 使用厚度参数
        }
        return Math.sin(v) > 0 ? 1 * h * 0.1 * thickness : -1 * thickness; // 使用厚度参数
      },
    };
  };

  const getPie3D = (
    pieData: StationTypeData[],
    internalDiameterRatio: number,
    thickness: number,
    widthRatio: number,
  ) => {
    let series = [];
    let startValue = 0;
    let endValue = 0;
    let k = (1 - internalDiameterRatio) / (1 + internalDiameterRatio);

    for (let i = 0; i < pieData.length; i++) {
      endValue = startValue + pieData[i].stationProportion / 100;
      const seriesItem = {
        name: pieData[i].stationTypeName,
        type: 'surface',
        parametric: true,
        wireframe: {
          show: false,
        },
        pieData: pieData[i],
        pieStatus: {
          selected: false,
          hovered: false,
          k,
        },
        itemStyle: {
          color: colors[i % colors.length],
        },
        parametricEquation: getParametricEquation(
          startValue,
          endValue,
          false,
          false,
          k,
          pieData[i].stationProportion / 100,
          thickness, // 传递厚度参数
          widthRatio, // 传递宽度参数
        ),
      };
      startValue = endValue;
      series.push(seriesItem);
    }

    return series;
  };

  const getOption = (pieData: StationTypeData[]) => {
    const series = getPie3D(pieData, internalDiameterRatio, thickness, widthRatio); // 传递内径比例、厚度和宽度参数

    return {
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b} : {c} ({d}%)',
        show: false,
      },
      legend: {
        show: true,
        orient: 'vertical',
        right: fitChartSize(12),
        top: 'center',
        itemGap: fitChartSize(12),
        itemHeight: 9,
        itemWidth: 9,
        icon: 'circle',
        textStyle: {
          color: '#fff',
          fontSize: fitChartSize(12),
          overflow: 'hidden',
          rich: {
            name: {
              width: fitChartSize(76),
              fontSize: fitChartSize(12),
              color: '#E1ECFF',
              overflow: 'truncate',
            },
            value: {
              fontSize: fitChartSize(12),
              padding: [0, 5, 0, 0],
              color: '#E1ECFF',
              overflow: 'truncate',
            },
            rate: {
              fontSize: fitChartSize(12),
              padding: [0, 0, 0, fitChartSize(8)],
              color: '#E1ECFF',
              overflow: 'truncate',
            },
          },
        },
        formatter: (name: string) => {
          const item = pieData.find((d) => d.stationTypeName === name);
          if (item) {
            const displayName =
              item.stationTypeName.length > 4
                ? item.stationTypeName.slice(0, 3) + '...'
                : item.stationTypeName;
            return `{name|${displayName} (${item.num})} {rate|${item.stationProportion}%}`;
          }
          return name;
        },
      },
      xAxis3D: {
        min: -1,
        max: 1,
      },
      yAxis3D: {
        min: -1,
        max: 1,
      },
      zAxis3D: {
        min: -1,
        max: 1,
      },
      grid3D: {
        show: false,
        boxHeight: 30,
        left: '-25%',
        right: '0',
        viewControl: {
          alpha,
          autoRotate,
          distance,
        },
        top: '-10%',
      },
      series,
    };
  };

  return (
    <div className={Styles.pieWrap} ref={pieWrapRef} style={{ display: 'flex' }}>
      <div style={{ width: '50%', height: '100%', position: 'relative' }}>
        {data && (
          <>
            <ReactECharts
              ref={chartRef1}
              option={getOption(data)}
              style={{ height: '100%', width: '100%' }}
            />
            <div className={Styles.pieBase}></div>
          </>
        )}
      </div>
      <div
        style={{
          width: '50%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          position: 'relative',
        }}
      >
        {statusData && (
          <>
            <ReactECharts
              ref={chartRef2}
              option={getOption(statusData)}
              style={{ height: '100%', width: '100%' }}
            />
            <div className={Styles.pieBase}></div>
          </>
        )}
      </div>
    </div>
  );
};

export default StationType;
